classdef nodeList < handle
% NODELIST  A class to represent a linked list.
   properties
      Size
   end
   properties(SetAccess = private)
      First
      Last
   end
    
   methods
      function list = nodeList()
	      list.Size = 0;
				list.First = [];
				list.Last = [];
      end
      
      function append(list, newNode)
	      if list.Size == 0
				  list.First = newNode;
				else
					newNode.insertAfter(list.Last);
				end
				list.Last = newNode;
				list.Size = list.Size + 1;
      end

      function appendInOrder(list, newNode)
	      if list.Size == 0
				  list.First = newNode;
				else
				  closest = list.findClosest(newNode);
					next = closest.Next;
					prev = closest.Prev;
					if isempty(prev)
					  prev = closest;
					end
					if isempty(next)
					  next = closest;
					end
					if distance(newNode, next) <= distance(newNode, prev)
						newNode.insertAfter(closest);
					else
						newNode.insertBefore(closest);
					end
				end
				list.Last = newNode;
				list.Size = list.Size + 1;
      end

      function remove(list, aNode) %make sure you delete if necessary!
			  node = list.find(aNode);
				if node == list.Last
				  list.Last = node.Prev;
				end
				if node == list.First
				  list.First = node.Next;
				end
				node.disconnect;
				list.Size = list.Size - 1;
      end

			function node = getFirst(list)
	       node = list.First;
			end

			function node = getLast(list)
	       node = list.Last;
			end

			function node = findClosest(list,aNode)
	      node = list.First;
				current = list.First;
				while ~isempty(current)
					if distance(current, node) < distance(current, aNode)
					  node = current;
					end
					current = current.Next;
				end
			end

			function node = find(list,aNode)
	      node = [];
				current = list.First;
				while ~isempty(current)
					if distance(current, aNode) == 0;
					  node = current;
						return;
					end
					current = current.Next;
				end
			end

			function node = findAt(list,pos)
	      node = [];
				current = list.First;
				node = current;
				distance = norm(current.Position-pos);
				while ~isempty(current)
					if norm(current.Position-pos) == 0;
					  node = current;
						return;
					else
					  %fprintf(1,'(%f,%f) %f %f\n',pos(1),pos(2),norm(current.Position-pos),distance);
					  if norm(current.Position-pos) < distance
							distance = norm(current.Position-pos);
							node = current;
						end
					end
					current = current.Next;
				end
			end

			function newList = findAdjacentTo(list,pos,h)
	      newList = nodeList();
				current = list.First;
				while ~isempty(current)
					if norm(current.Position-pos) <= h
					  newNode = dlnode(current.Position,current.V);
					  newList.append(newNode);
					end
					current = current.Next;
				end
			end

			function node = findMinV(list)
	      node = list.First;
				current = list.First;
				while ~isempty(current)
					if current.V < node.V
					  node = current;
					end
					current = current.Next;
				end
			end

      function insertAfter(list, newNode, nodeAfter)
	      newNode.insertAfter(nodeAfter);
				list.Size = list.Size + 1;
			end

			function plot(list,symbol,faceColor,fig)
			  current = list.First;
				figure(fig);
			  while ~isempty(current)
	         plot(current,symbol,faceColor);
	         current = current.Next;
				end
			end

      function resetValues(list)
      % DISP  Displays a link node.
			  current = list.First;
			  while ~isempty(current)
	         current.V = inf;
	         current = current.Next;
				end
      end

      function disp(list)
      % DISP  Displays a link node.
			  current = list.First;
			  while ~isempty(current)
	         disp(current);
	         current = current.Next;
				end
      end
   end % methods
end % classdef
